import React, { Component } from 'react';
import { Affix, Button, Spin, Icon, Menu, Collapse, message, Modal } from 'antd';
import 'styles/data-center/report-management/custom-report/index-refactor.scss';
import { deepCopy, messages, removeArrayItemByKey, scrollToMyDestination } from 'share/common';
import withDragDropContext from 'components/with-dnd-context';
import FakeDropLayout from './drop-target/fake-drop-layout';
import FullScreen from 'components/full-screen';
import EditCustomReport
  from 'containers/data-center/report-management/custom-report/edit-custom-report';
import CustomReportService
  from 'containers/data-center/report-management/custom-report/custom-report.service';
import debounce from 'lodash.debounce';

import {
  graphList,
  tableTemplateList,
  criteriaTemplateList, iconMap
} from 'containers/data-center/report-management/custom-report/custom-report.modal';
import menuRoute from 'routes/menuRoute';
import AdvancedSearch from 'components/advanced-search';
import UniversalReportService
  from 'containers/data-center/report-management/custom-report/graphic/default-value/custom-report.service';
import { connect } from 'react-redux';
import { clearPending } from 'share/httpFetch';
import Graphic from './graphic';
import Muuri from 'muuri';


const Panel = Collapse.Panel;
const confirm = Modal.confirm;

function mapStateToProps(state) {
  return {
    language: state.main.language,
    company: state.login.company,
    tenant: state.login.tenant
  };
}

@connect(mapStateToProps)

class CustomReport extends Component {
  constructor(props) {
    super(props);
    this.state = {
      customReportName: messages('basic-10.key173')/*自定义报表*/, //自定义报表名
      loading: true,
      editVisible: false, //第二层 编辑报表详情 fullScreen 开关
      sourceReportIdArray: [], //所有数据模型ID数组
      widgetList: [], // 图表list
      searchForm: [], // 处理后的 筛选器数据 对应AdvanceSearch 的 searchForm
      criteriaData: [], //筛选器数据 存储的地方
      currentReportPrivate: {}, // 各报表私有配置的载体 (不知道这是干嘛的， 因为格式化 searchForm 需要这个)
      currentEdit: undefined, //进入单个图表编辑时 编辑的对象储存
      currentSequence: null, //当前图表的 id 排序数组
    };
    this.SingleKey = 1000000; //添加图表时 临时 唯一 key
    this.resizeWindow = debounce(this.resizeWindow, 500); //延时 resize Window
    this.actualDelete = debounce(this.actualDelete, 300); //延时 真正的删除图标
    this.handleOnDragDroppedItem = debounce(this.handleOnDragDroppedItem, 50);
    this.removeTempChart = debounce(this.removeTempChart, 1000);
    this.grid = null;
  }

  componentDidMount() {
    this.initData(); //初始化数据
    const { onRef } = this.props;
    onRef && (onRef(this));
  }

  componentWillUnmount() {
    clearPending();
    this.grid.destroy();
  }

  /** 初始化数据 完成了以下事情：
   1. customReportName  自定义报表名
   2. widgetList 图表 List 包含图表各种信息
   3. criteriaData 筛选器信息 这个在后端数据里 是和 图表 一起的。 所以 筛选器也是 变相的 '图表'
   4. sourceReportIdArray 所有图表的 数据模型 ID 数组 在 编辑筛选器时会用到
   5. searchForm 通过处理 criteriaData 筛选器里的 信息 处理好的 advanceSearch 能识别的 searchForm

   本页面功能：
   1. 图表的增删
   2. 图表的布局修改 全屏/半屏
   3. 图表/筛选器 的 编辑入口
   4. 自定义报表已配置筛选器的展示
   5. 配置好的图表 基于真实数据的展示
   */
  initData = (freshId) => {
    this.setState({ loading: true });
    const { customReportData } = this.props;
    CustomReportService.getCustomReportDetail(customReportData.id)
      .then((res) => {
        if (res.status === 200) {
          let copyData = deepCopy(res.data);
          let reportCharts = copyData.reportCharts;
          let sourceReportIdArray = [];
          if (reportCharts && reportCharts.length) {
            res.data.reportCharts.forEach((item, index) => {
              reportCharts[index].uniqueKey = item.id;
              reportCharts[index].key = item.chartType;
              reportCharts[index].set = true;
              if (item.chartType !== 'criteria') {
                sourceReportIdArray.push(item.sourceReportId);
              }
            });
          }
          let widgetList = reportCharts && reportCharts.length && reportCharts.filter(item => item.key !== 'criteria') || [];
          let criteriaData = reportCharts && reportCharts.length && reportCharts.filter(item => item.key === 'criteria') || [];
          let searchForm = this.handleSearchForm(criteriaData[0]);
          sourceReportIdArray = sourceReportIdArray.filter((item, index, self) => self.indexOf(item) === index);
          this.setState({
            customReportName: res.data.reportName,
            widgetList,
            criteriaData,
            sourceReportIdArray,
            searchForm,
            loading: false
          }, ()=>{
            this.initMuuri(widgetList);
            if (freshId) {
              setTimeout(()=>{
                this[`GraphicRef-${freshId}`].initMe();
              }, 300)
            }
          });
        }
      });
  };

  initMuuri = (widgetList) => {
    if (this.grid) {
      let data = this.getMuuriItemKeyArray(this.grid);
      widgetList.forEach((item)=>{
        let target = data.find(id => item.id === id);
        if (target === undefined) {
          let items = this.grid.add(document.getElementById(item.id), { index: 0, active: false });
          this.grid.show(items);
        }
      })
      return
    }
    this.grid = new Muuri('.page-graph-groups', {
      dragEnabled: true,
      dragContainer: document.getElementById('custom-report-drag-container'),
      dragAutoScroll: {
        targets: (item) => {
          return [
            { element: document.getElementById('scroll-container'), priority: 0 }
          ];
        }
      },
      showDuration: 500,
      visibleStyles: {
        opacity: 1,
        transform: 'scale(1)'
      },
      dragStartPredicate: this.dragStartPredicate,
      layoutOnResize: true,
      layoutOnInit: true,
      dragHandle: '.ant-card-head-title',
      dragSortPredicate: {
        threshold: 50,
        action: 'move',
      },
      dragPlaceholder: {
        enabled: true,
      },
      itemPlaceholderClass: 'muuri-item-placeholder-index',
      itemReleasingClass: 'muuri-item-releasing-index',
      itemDraggingClass: 'muuri-item-dragging-index',
    }).on('dragReleaseEnd', this.gridDragEnd);
    window.grid = this.grid;
  };

  dragStartPredicate = (item, event) => {
    // Prevent first item from being dragged.
    let data = this.judgeIsOneMore(this.state.widgetList);
    if (data.result) {
      message.warn(messages('basic-10.key231',{arg1: data.name})/*请编辑【{arg1}】后，再进行拖动排序*/);
      return false;
    }
    // For other items use the default drag start predicate.
    return Muuri.ItemDrag.defaultStartPredicate(item, event);
  }

  gridDragEnd = () => {
    let data = this.getMuuriItemKeyArray(this.grid);
    this.saveNewSort(data);
  };

  saveNewSort = (sortArray) => {
    let unshiftArray = deepCopy(sortArray);
    if (this.state.criteriaData && this.state.criteriaData.length > 0) {
      unshiftArray.unshift(this.state.criteriaData[0].id)
    }
    CustomReportService.sortChartsSequence(this.props.customReportData.id, unshiftArray)
      .then((resp) => {
        if (resp.status === 200) {
          this.setState({currentSequence: unshiftArray})
          // message.success(messages('basic-10.key107')/*保存成功*/);
          // this.setState({ btnLoading: false });
          // this.props.onCancel && this.props.onCancel();
        }
      })
      .catch(() => {
        // this.setState({ btnLoading: false });
      });
  }

  getMuuriItemKeyArray = (grid) => {
    let itemIds = grid.getItems()
      .map((item) => {
        return item.getElement()
          .getAttribute('data-id');
      });
    return itemIds;
  };

  //根据拿到的筛选器数据 格式化 searchForm 数据
  handleSearchForm = (data) => {
    let result = [];
    if (data && data.reportChartDetails && data.reportChartDetails.length) {
      result = UniversalReportService.searchFormFactory({
        context: this,
        list: data.reportChartDetails.map((item) => {
          return {
            criteriaCode: item.criteriaCode,
            criteriaName: item.fieldDisplayName,
            criteriaPropName: `${item.sourceReportId}_${item.criteriaPropName}`,
            defaultValue: item.defaultValue
          };
        })
      });
    }
    return result;
  };

  //点击 页面左上角 返回的处理
  onPageCanceled = () => {
    const { widgetList } = this.state;
    let doseNotFinish = false;
    widgetList.forEach((item) => {
      if (!item.set) {
        doseNotFinish = true;
      }
    });
    if (doseNotFinish) {
      confirm({
        title: messages('basic-10.key99')/*警告*/,
        content: messages('basic-10.key174')/*未完成图表配置，退出会丢失已配置数据，确定退出？*/,
        okText: messages('common.ok')/*确定*/,
        cancelText: messages('common.cancel')/*取消*/,
        onOk: () => {
          this.props.onCancel && this.props.onCancel();
        },
        onCancel() {
        },
      });
    } else {
      this.props.onCancel && this.props.onCancel();
    }
  };
  // 渲染头信息
  renderPageHeader = () => {
    const { customReportName } = this.state;
    return <div className={'page-header'}>
      <div className="left">
        <Icon onClick={this.onPageCanceled} type="left"/>
        <span
          className={'report-name'}>{customReportName || messages('basic-10.key173')/*自定义报表*/}</span>
      </div>
      <div className="right">
        <Button onClick={this.goToPreview}>{messages('basic-10.key57')/*预览*/}</Button>
      </div>
    </div>;
  };

  //前往预览页面
  goToPreview = (e) => {
    e.preventDefault();
    const { customReportData } = this.props;
    let targetRoute = 'custom-report-preview';
    let path = menuRoute.getRouteItem(targetRoute, 'key')
      .url
      .replace(':id', customReportData.id);
    if (path.includes(':reportName')) {
      path = path.replace(':reportName', customReportData.reportName);
    }
    window.open(path, '_blank');
  };

  //判断是否有未设置的图形表 返回状态以及该图表名称
  judgeIsOneMore = (widgetList) => {
    let result = false;
    let name = '';
    widgetList.map(item => {
      if (!item.set) {
        result = true;
        name = item.chartName;
      }
    });
    return { result, name };
  };

  //图形表除了拖拽外还可以 点击 直接新增 默认加到 最后     以下为 点击新增处理
  handleItemClick = (item) => {
    let copyItem = deepCopy(item);
    const { widgetList, criteriaData, currentSequence } = this.state;
    let data = this.judgeIsOneMore(widgetList);
    if (data.result) {
      message.warn(messages('basic-10.key175',{arg1: data.name})/*请编辑【{arg1}】后，再添加新图表*/);
    } else {
      let newCurrentSequence = [];
      let copyData = deepCopy(widgetList);
      let copySpliceIndex = 0;
      if (criteriaData.length) {
        copySpliceIndex += 1;
      }
      if (currentSequence) {
        newCurrentSequence = currentSequence
      } else {
        newCurrentSequence = copyData.map(item => item.id);
        if (criteriaData.length) {
          newCurrentSequence.unshift(criteriaData[0].id);
        }
      }
      copyItem.order = widgetList.length;
      copyItem.uniqueKey = this.SingleKey++;
      copyItem.currentSequence = newCurrentSequence;
      copyItem.spliceIndex = copySpliceIndex;
      copyData.push(copyItem);
      this.setState({ widgetList: copyData }, () => {
        scrollToMyDestination(this.rightRef, 0);
        let items = this.grid.add(document.getElementById(copyItem.uniqueKey), { index: 0, active: false });
        this.grid.show(items);
      });
    }
  };

  // 渲染 可添加的图形表 以及 table 明细表
  renderPageContentLeft = () => {
    return (
      <div className={'page-body-left'}>
        <FakeDropLayout/>
        <Collapse bordered={false} defaultActiveKey={['1', '2']}>
          <Panel header={messages('basic-10.key176')/*图形表*/} key={'1'}>
            {
              graphList.map(widget => <div key={widget.key}
                                           className={'menu-item-content'}
                                           onClick={()=>{this.handleItemClick(widget)}}>
                <div className="img-wrapper">
                  <img onMouseDown={e=>e.preventDefault()} className="img" src={iconMap[widget.key]} alt={widget.chartName}/>
                </div>
                <div className={'menu-title'}>{widget.chartName}</div>
                <svg
                  width="16px"
                  height="16px"
                  viewBox="0 0 16 16"
                  version="1.1"
                  className='icon-add'
                >
                  <path d="M8,0 C12.418278,-8.11624501e-16 16,3.581722 16,8 C16,12.418278 12.418278,16 8,16 C3.581722,16 5.41083001e-16,12.418278 0,8 C-5.41083001e-16,3.581722 3.581722,8.11624501e-16 8,0 Z M8,3.75 C7.58578644,3.75 7.25,4.08578644 7.25,4.5 L7.25,4.5 L7.25,7.25 L4.5,7.25 L4.39822944,7.25684662 C4.03215388,7.30650904 3.75,7.62030423 3.75,8 C3.75,8.41421356 4.08578644,8.75 4.5,8.75 L4.5,8.75 L7.25,8.75 L7.25,11.5 L7.25684662,11.6017706 C7.30650904,11.9678461 7.62030423,12.25 8,12.25 C8.41421356,12.25 8.75,11.9142136 8.75,11.5 L8.75,11.5 L8.75,8.75 L11.5,8.75 L11.6017706,8.74315338 C11.9678461,8.69349096 12.25,8.37969577 12.25,8 C12.25,7.58578644 11.9142136,7.25 11.5,7.25 L11.5,7.25 L8.75,7.25 L8.75,4.5 L8.74315338,4.39822944 C8.69349096,4.03215388 8.37969577,3.75 8,3.75 Z" id="custom-report-add-icon" />
                </svg>
              </div>)
            }
          </Panel>
          <Panel header={messages('basic-10.key177')/*明细表*/} key={'2'}>
            {
              tableTemplateList.map(widget => <div key={widget.key}
                                                   className={'menu-item-content'}
                                                   onClick={()=>{this.handleItemClick(widget)}}>
                <div className="img-wrapper">
                  <img onMouseDown={e=>e.preventDefault()} className="img" src={iconMap[widget.key]} alt={widget.chartName}/>
                </div>
                <div className={'menu-title'}>{widget.chartName}</div>
                <svg
                  width="16px"
                  height="16px"
                  viewBox="0 0 16 16"
                  version="1.1"
                  className='icon-add'
                >
                  <path d="M8,0 C12.418278,-8.11624501e-16 16,3.581722 16,8 C16,12.418278 12.418278,16 8,16 C3.581722,16 5.41083001e-16,12.418278 0,8 C-5.41083001e-16,3.581722 3.581722,8.11624501e-16 8,0 Z M8,3.75 C7.58578644,3.75 7.25,4.08578644 7.25,4.5 L7.25,4.5 L7.25,7.25 L4.5,7.25 L4.39822944,7.25684662 C4.03215388,7.30650904 3.75,7.62030423 3.75,8 C3.75,8.41421356 4.08578644,8.75 4.5,8.75 L4.5,8.75 L7.25,8.75 L7.25,11.5 L7.25684662,11.6017706 C7.30650904,11.9678461 7.62030423,12.25 8,12.25 C8.41421356,12.25 8.75,11.9142136 8.75,11.5 L8.75,11.5 L8.75,8.75 L11.5,8.75 L11.6017706,8.74315338 C11.9678461,8.69349096 12.25,8.37969577 12.25,8 C12.25,7.58578644 11.9142136,7.25 11.5,7.25 L11.5,7.25 L8.75,7.25 L8.75,4.5 L8.74315338,4.39822944 C8.69349096,4.03215388 8.37969577,3.75 8,3.75 Z" id="custom-report-add-icon" />
                </svg>
              </div>)
            }
          </Panel>
        </Collapse>
      </div>
    );
  };

  //点击 全屏/半屏 图表的处理
  onStretchItem = (widget) => {
    const { widgetList } = this.state;
    let copyData = deepCopy(widgetList);
    widgetList.forEach((chart, index) => {
      if (chart.id === widget.id) {
        copyData[index].changingScreen = true;
      }
    });
    this.setState({ widgetList: copyData }, () => {
      let params = {
        id: widget.id,
        showScreen: widget.showScreen === 'half' ? 'all' : 'half'
      };
      CustomReportService.switchSingleChartScreenSize(params)
        .then((res) => {
          if (res.status === 200) {
            widgetList.forEach((item, index) => {
              if ((item.id === widget.id) || (item.uniqueKey === widget.uniqueKey)) {
                copyData[index].showScreen = (widget.showScreen === 'half' ? 'all' : 'half');
                delete copyData[index].changingScreen;
              }
            });
            this.setState({ widgetList: copyData }, () => {
              this.resizeWindow();
            });
          }
        });
    });
  };

  //手动触发 window resize 好让 echart 图表 重新 渲染 以适配最新的 宽度
  resizeWindow = () => {
    let myEvent = new Event('resize');
    window.dispatchEvent(myEvent);
  };

  //删除图表的处理
  onDeleteItem = (widget) => {
    confirm({
      title: messages('basic-10.key2')/*确认删除*/,
      okText: messages('basic-10.key3')/*确认*/,
      cancelText: messages('common.cancel')/*取消*/,
      iconType: 'exclamation-circle',
      onOk: () => {
        if (widget.id) {
          let params = { id: widget.id };
          CustomReportService.deleteSingleChart(params)
            .then((res) => {
              if (res.status === 200) {
                // this.initData();
                this.actualDelete(widget);
              }
            });
        } else {
          this.actualDelete(widget);
        }
      },
      onCancel() {
      },
    });
  };

  //真正的删除 上个function 是处理逻辑的
  actualDelete = (widget, noMessage) => {
    let deleteItem = this.grid.getItems().filter((item) => {return item.getElement().getAttribute('data-id') === (widget.uniqueKey || widget.id).toString()});
    this.grid.remove(deleteItem, { removeElements: false });
    if (!noMessage)
      message.success(messages('common.delete.successful')/*删除成功*/);
    this.deleteFromState(widget);
  };

  deleteFromState = (widget) => {
    const { widgetList } = this.state;
    let copyData = deepCopy(widgetList);
    copyData = removeArrayItemByKey(copyData, widget, 'uniqueKey');
    this.setState({ widgetList: copyData, loading: false });
  }

  removeTempChart = (widget) => {
    if (!widget.set) {
      this.actualDelete(widget, true)
    }
  }

  //编辑筛选器/图表
  onEditItem = (widget, editCriteria) => {
    if (editCriteria) {
      const { widgetList } = this.state;
      let length = widgetList && widgetList.length > 0;
      if (length) {
        let doseNotFinish = false;
        let name = '';
        widgetList.forEach((item) => {
          if (!item.set) {
            doseNotFinish = true;
            name = item.chartName;
          }
        });
        if (doseNotFinish) {
          message.warn(messages('basic-10.key178',{arg1: name})/*请先编辑【{arg1}】*/);
        } else {
          this.setState({ editVisible: true, currentEdit: widget }, () => {
            this.props.handleInnerVisible && this.props.handleInnerVisible(true);
            clearPending();
          });
        }
      } else {
        message.warn(messages('basic-10.key179')/*请先从左侧添加报表元素*/);
      }
    } else {
      this.setState({ editVisible: true, currentEdit: widget }, () => {
        this.props.handleInnerVisible && this.props.handleInnerVisible(true);
        clearPending();
        this.removeTempChart(widget);
      });
    }
  };

  //处理 拖动 已放置的 图表  （这块有点问题，后面处理 已放置图表的拖动）
  handleOnDragDroppedItem = (widget) => {
    const { widgetList } = this.state;
    let copyData = deepCopy(widgetList);
    copyData = removeArrayItemByKey(copyData, widget, 'id');
    this.setState({ widgetList: copyData });
  };

  // 渲染 所有图表
  renderAllCharts = () => {
    let { widgetList, loading } = this.state;

    return <div className="page-content" ref={ref => this.pageContentRef = ref}>
      <div className="page-graph-groups" ref={ref => this.chartGrid = ref}>
        {
          widgetList.map((item) => {
            return <div
              id={item.id || item.uniqueKey}
              key={item.id || item.uniqueKey}
              data-id={item.id || item.uniqueKey}
              className={item.showScreen === 'half' ? 'half' : 'full'}
            >
              <Graphic
                key={item.id || item.uniqueKey}
                noRefresh
                displayMode={false}
                onRef={ref => this[`GraphicRef-${item.id || item.uniqueKey}`] = ref}
                changingScreen={item.changingScreen}
                onStretchItem={(item) => {
                  this.onStretchItem(item);
                }}
                onDeleteItem={(item) => {
                  this.onDeleteItem(item);
                }}
                onEditItem={(item) => {
                  this.onEditItem(item);
                }}
                widget={Object.assign({}, item)}
              />
            </div>;
          })
        }
      </div>
    </div>;
  };

  render() {
    const { loading, editVisible, currentEdit, sourceReportIdArray, criteriaData, customReportName, searchForm } = this.state;
    return (
      <div className="custom-report-wrapper">
        <Spin spinning={loading}>
          <div style={{ height: '100vh' }}>
            {this.renderPageHeader()}
            <div className={'page-body'}>
              <div className="left">
                {this.renderPageContentLeft()}
              </div>
              <div className="right" id={'scroll-container'} ref={ref => this.rightRef = ref}>
                {searchForm.length ?
                  <div className='advanced-search-box'>
                    <AdvancedSearch
                      pinnedList={searchForm.map(item => item.id)}
                      searchButton={{
                        props: { disabled: true },
                        text: messages('common.search')/*搜索*/
                      }}
                      resetButton={{
                        props: { disabled: true },
                        text: messages('common.reset')/*重置*/
                      }}
                      title={customReportName}
                      searchForm={searchForm}
                      notLoadWhenMount
                      hide={['advanced-pinned-list']}
                    />
                  </div> : null
                }
                <div className="page-controller" onClick={() => {
                  this.onEditItem(criteriaData[0] || criteriaTemplateList[0], true);
                }}>
                  <span><Icon type="filter"/>{messages('basic-10.key101')/*编辑筛选器*/}</span>
                </div>
                {this.renderAllCharts()}
              </div>
            </div>
          </div>
        </Spin>
        {editVisible && !loading &&
        <FullScreen animateIn="fadeIn" animateOut="fadeOut" style={{ background: '#f7f8fa' }}>
          <EditCustomReport
            sourceReportIdArray={sourceReportIdArray}
            customReportData={this.props.customReportData}
            confirmOpened={this.props.confirmOpened}
            currentEdit={currentEdit}
            onCancel={(dontRefresh, freshId) => {
              this.setState({ editVisible: false }, () => {
                this.props.handleInnerVisible && this.props.handleInnerVisible(false)
              });
              !dontRefresh && this.initData(freshId);
            }}
          />
        </FullScreen>
        }
      </div>
    );
  }
}

CustomReport.propTypes = {
  onCancel: React.PropTypes.func
};

export default withDragDropContext(CustomReport);
